const express = require('express');
const router = express.Router();
const jwt = require('jsonwebtoken');
const User = require('../models/User');
const { validationResult } = require('express-validator');
const { body } = require('express-validator');
const rateLimit = require('express-rate-limit');
const bcrypt = require('bcryptjs');

// 登录失败限流
const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分钟
  max: 5, // 限制5次尝试
  message: '登录尝试次数过多，请稍后再试',
  skipSuccessfulRequests: true
});

// 密码重置限流
const resetLimiter = rateLimit({
  windowMs: 60 * 60 * 1000, // 1小时
  max: 3, // 限制3次请求
  message: '密码重置请求次数过多，请稍后再试'
});

// 验证中间件
const validateSignup = [
  body('email').isEmail().withMessage('请输入有效的邮箱地址'),
  body('password').isLength({ min: 6 }).withMessage('密码至少需要6个字符'),
  body('name').isLength({ min: 2 }).withMessage('用户名至少需要2个字符')
];

const validateLogin = [
  body('email').isEmail().withMessage('请输入有效的邮箱地址'),
  body('password').notEmpty().withMessage('密码不能为空')
];

// 生成JWT令牌
const generateToken = (user) => {
  return jwt.sign(
    { id: user._id, email: user.email, role: user.role },
    process.env.JWT_SECRET,
    { expiresIn: '7d' }
  );
};

// 设置HTTP-only cookie
const setAuthCookie = (res, token) => {
  res.cookie('token', token, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'strict',
    maxAge: 7 * 24 * 60 * 60 * 1000 // 7天
  });
};

// 登录路由
router.post('/login', loginLimiter, validateLogin, async (req, res) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    const { email, password } = req.body;
    
    // 查找用户
    const user = await User.findOne({ email }).select('+password');
    if (!user) {
      // 模拟密码验证延迟，防止时序攻击
      await bcrypt.compare(password, '$2a$10$fakehashforsecurity');
      return res.status(401).json({ message: '邮箱或密码错误' });
    }

    // 验证密码
    const isMatch = await user.comparePassword(password);
    if (!isMatch) {
      return res.status(401).json({ message: '邮箱或密码错误' });
    }

    // 生成令牌
    const token = generateToken(user);
    
    // 设置HTTP-only cookie
    setAuthCookie(res, token);
    
    res.json({
      user: user.toJSON()
    });
  } catch (error) {
    console.error('登录错误:', error);
    res.status(500).json({ message: '服务器错误' });
  }
});

// 注册路由
router.post('/signup', validateSignup, async (req, res) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    const { email, password, name } = req.body;

    // 检查邮箱是否已存在
    const existingUser = await User.findOne({ email });
    if (existingUser) {
      return res.status(409).json({ message: '该邮箱已被注册' });
    }

    // 创建新用户
    const user = new User({
      email,
      password,
      name
    });

    await user.save();

    // 生成令牌
    const token = generateToken(user);

    // 设置HTTP-only cookie
    setAuthCookie(res, token);

    res.status(201).json({
      user: user.toJSON()
    });
  } catch (error) {
    console.error('注册错误:', error);
    res.status(500).json({ message: '服务器错误' });
  }
});

// 登出路由
router.post('/logout', (req, res) => {
  res.clearCookie('token', {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'strict'
  });
  res.json({ message: '已登出' });
});

// 获取当前用户信息
router.get('/me', async (req, res) => {
  try {
    // 从cookie获取令牌
    const token = req.cookies.token;
    if (!token) {
      return res.status(401).json({ message: '未提供认证令牌' });
    }

    // 验证令牌
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    
    // 查找用户
    const user = await User.findById(decoded.id);
    if (!user) {
      return res.status(401).json({ message: '用户不存在' });
    }

    res.json(user.toJSON());
  } catch (error) {
    if (error.name === 'JsonWebTokenError') {
      return res.status(401).json({ message: '无效的认证令牌' });
    }
    if (error.name === 'TokenExpiredError') {
      return res.status(401).json({ message: '认证令牌已过期' });
    }
    console.error('获取用户信息错误:', error);
    res.status(500).json({ message: '服务器错误' });
  }
});

// 密码重置请求
router.post('/reset-password-request', resetLimiter, async (req, res) => {
  try {
    const { email } = req.body;
    
    // 查找用户
    const user = await User.findOne({ email });
    if (!user) {
      // 即使用户不存在也返回成功，防止邮箱枚举
      return res.json({ message: '如果邮箱存在，重置链接已发送' });
    }

    // 生成重置令牌
    const resetToken = jwt.sign(
      { id: user._id },
      process.env.JWT_SECRET,
      { expiresIn: '1h' }
    );

    // TODO: 发送重置邮件
    // 这里应该实现邮件发送逻辑

    res.json({ message: '如果邮箱存在，重置链接已发送' });
  } catch (error) {
    console.error('密码重置请求错误:', error);
    res.status(500).json({ message: '服务器错误' });
  }
});

module.exports = router; 